﻿#region Imported Libraries
using System;
using System.IO;
using org.webguvenligi.NSecureImageLib.GraphicFileFormats.Utilities;
#endregion

namespace org.webguvenligi.NSecureImageLib.GraphicFileFormats 
{
    public abstract class BaseImageParser : IDisposable
    {
        /// <summary>
        /// Constructor For Parsing The Graphical Image Files.
        /// </summary>
        /// <remarks>
        /// Magic Number Check Is Already Done Here, So Extending Classes Should Expect The BinaryStream
        /// After The Header Check Completed.
        /// </remarks>
        /// <param name="bitmapStream"></param>
        protected BaseImageParser(Stream bitmapStream) {            
            if (bitmapStream == null || !bitmapStream.CanRead || !bitmapStream.CanSeek)
                throw new InvalidDataException();            
            this.ImageStream = bitmapStream;            
            this.ImageStream.Position = 0;
            if (this.ImageStream.Length < (long)HeaderSignature.Length ||
                (!this.ImageStream.CompareByteArray(HeaderSignature)) || !ParseImage())
                throw new System.IO.InvalidDataException(FormatExceptionMessage);
        }
        
        /// <summary>
        /// Writes The Image File Removing Metadata Tags To The Given Stream
        /// </summary>
        /// <param name="targetStream"></param>
        /// <param name="removeMetadataTags"></param>
        public abstract void WriteImage(Stream targetStream,
                               bool removeMetadataTags);
        /// <summary>
        /// Writes The Image File Removing Metadata Tags To The Given Stream
        /// </summary>
        /// <param name="fileName"></param>
        /// <param name="removeMetadataTags"></param>
        public void WriteImage(string fileName,
                               bool removeMetadataTags)
        {
            WriteImage(new FileStream(fileName,
                                      FileMode.Create,
                                      FileAccess.ReadWrite),
                                      removeMetadataTags);
        }

        protected abstract byte[] HeaderSignature
        {
            get;
        }

        private Stream _ImageStream;
        
        protected Stream ImageStream
        {
            get;
            private set;
        }
        protected abstract string FormatExceptionMessage
        {
            get;
        }
        protected abstract bool ParseImage();

        #region IDisposable Members
        
        public void Dispose()
        {
            if (this._ImageStream != null)
            {
                this._ImageStream.Dispose();
                this._ImageStream = null;
            }
        }

        #endregion
    }
}